package fr.obsmip.sedoo.client.activity;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

import fr.obsmip.sedoo.client.ClientFactory;
import fr.obsmip.sedoo.client.Constants;
import fr.obsmip.sedoo.client.ShortcutFactory;
import fr.obsmip.sedoo.client.event.ActionEventConstant;
import fr.obsmip.sedoo.client.message.Message;
import fr.obsmip.sedoo.client.place.ExperimentalSiteEditingPlace;
import fr.obsmip.sedoo.client.place.ExperimentalSiteEntryDisplayingPlace;
import fr.obsmip.sedoo.client.place.ObservatoryEditingPlace;
import fr.obsmip.sedoo.client.place.ObservatoryEntryCreationPlace;
import fr.obsmip.sedoo.client.service.MetadataService;
import fr.obsmip.sedoo.client.service.MetadataServiceAsync;
import fr.obsmip.sedoo.client.ui.ObservatoryEntryView;
import fr.obsmip.sedoo.client.ui.ObservatoryEntryView.ObservatoryEntryPresenter;
import fr.obsmip.sedoo.client.ui.metadata.observatory.ExperimentalSiteNameDialogContent;
import fr.obsmip.sedoo.client.ui.misc.BreadCrumb;
import fr.obsmip.sedoo.client.ui.misc.Shortcut;
import fr.obsmip.sedoo.client.ui.table.ObservatoryPersonTable;
import fr.obsmip.sedoo.shared.domain.ObservatoryDTO;
import fr.sedoo.commons.client.event.ActionStartEvent;
import fr.sedoo.commons.client.event.NotificationEvent;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.service.DefaultAbstractCallBack;
import fr.sedoo.commons.client.util.StringUtil;
import fr.sedoo.commons.client.widget.ConfirmCallBack;
import fr.sedoo.commons.client.widget.DialogBoxTools;
import fr.sedoo.commons.client.widget.dialog.OkCancelDialog;
import fr.sedoo.commons.client.widget.editing.ValidationAlert;
import fr.sedoo.commons.shared.domain.GeographicBoundingBoxDTO;
import fr.sedoo.metadata.shared.domain.MetadataDTO;
import fr.sedoo.metadata.shared.domain.MetadataSummaryDTO;

public class ObservatoryEntryEditingActivity extends AbstractMetadataEditingActivity implements ObservatoryEntryPresenter {

	private String observatoryUuid;
	private String observatoryName;
	private String mode;

	public ObservatoryEntryEditingActivity(ObservatoryEditingPlace place, ClientFactory clientFactory) {
		super(clientFactory, place);
		if (StringUtil.isNotEmpty(place.getObservatoryUuid()))
		{
			observatoryUuid = place.getObservatoryUuid();
			mode = Constants.MODIFY;
		}
		else
		{
			observatoryName = place.getObservatoryName();
			mode = Constants.CREATE;
		}
	}

	private static final MetadataServiceAsync METADATA_SERVICE = GWT.create(MetadataService.class);
	private ExperimentalSiteNameDialogContent content;

	@Override
	public void start(final AcceptsOneWidget containerWidget, EventBus eventBus) {

		if (isValidUser() == false)
		{
			goToLoginPlace();
			return;
		}
		if (mode.compareTo(Constants.CREATE)==0)
		{
			if (StringUtil.isEmpty(observatoryName))
			{
				clientFactory.getPlaceController().goTo(new ObservatoryEntryCreationPlace());
				return;
			}
		}
		sendActivityStartEvent();
		containerWidget.setWidget(clientFactory.getProgressView());
		if (mode.compareTo(Constants.CREATE)==0)
		{

			ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.refreshing(), ActionEventConstant.REFRESHING, true);
			clientFactory.getEventBus().fireEvent(startEvent);
			broadcastActivityTitle(Message.INSTANCE.observatoryEditingViewCreationHeader());
			List<Shortcut> shortcuts = new ArrayList<Shortcut>();
			shortcuts.add(ShortcutFactory.getWelcomeShortcut());
			shortcuts.add(ShortcutFactory.getObservatoryEntryCreationShortcut());
			clientFactory.getBreadCrumb().refresh(shortcuts);
			previousHash="";
			ObservatoryDTO newObservatory = clientFactory.createObservatoryDTO(observatoryName);
			view = clientFactory.getObservatoryEditingView();
			((ObservatoryEntryView) view).setPresenter(this);
			containerWidget.setWidget(view.asWidget());
			view.edit(newObservatory);
			clientFactory.getEventBus().fireEvent(startEvent.getEndingEvent());
		}
		else
		{
			broadcastActivityTitle(Message.INSTANCE.observatoryEditingViewModificationHeader());
			ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.OBSERVATORY_LOADING_EVENT, true);
			clientFactory.getEventBus().fireEvent(startEvent);
			METADATA_SERVICE.getObservatoryByUuid(observatoryUuid, clientFactory.getDisplayLanguages(), new DefaultAbstractCallBack<ObservatoryDTO>(startEvent, clientFactory.getEventBus()) {

				@Override
				public void onSuccess(ObservatoryDTO result) {
					super.onSuccess(result);
					observatoryName = result.getObservatoryName();
					view = clientFactory.getObservatoryEditingView();
					((ObservatoryEntryView) view).setPresenter(ObservatoryEntryEditingActivity.this);
					containerWidget.setWidget(view.asWidget());
					previousHash = result.getHash();
					traceHash(result);
					view.edit(result);
					List<Shortcut> shortcuts = new ArrayList<Shortcut>();
					shortcuts.add(ShortcutFactory.getWelcomeShortcut());
					shortcuts.add(ShortcutFactory.getObservatoryEntryManagementShortcut());
					shortcuts.add(ShortcutFactory.getObservatoryModificationShortcut(result.getObservatoryName(), observatoryUuid));
					clientFactory.getBreadCrumb().refresh(shortcuts);
				}

			});
		}

	}
	
	
	private void traceHash(ObservatoryDTO result) {
//		System.out.println("Abstract :"+result.getIdentificationPart().getResourceAbstract().getHash());
//		System.out.println("Title :"+result.getIdentificationPart().getResourceTitle().getHash());
//		System.out.println("Geo: "+result.getGeographicalLocationPart().getHash());
		
	}



	@Override
	public void save(final MetadataDTO observatoryDTO) 
	{
		List<ValidationAlert> validationResult = observatoryDTO.validate();
		if (validationResult.isEmpty() == false)
		{
			DialogBoxTools.popUpScrollable(CommonMessages.INSTANCE.error(), ValidationAlert.toHTML(validationResult), DialogBoxTools.HTML_MODE);
			return;
		}
		else
		{

			ActionStartEvent startEvent = new ActionStartEvent(Message.INSTANCE.saving(), ActionEventConstant.OBSERVATORY_SAVING_EVENT, true);
			clientFactory.getEventBus().fireEvent(startEvent);
			ObservatoryDTO aux = (ObservatoryDTO) observatoryDTO;
			METADATA_SERVICE.saveObservatory(observatoryDTO, aux.getObservatoryName(), clientFactory.getMetadataLanguages(), new DefaultAbstractCallBack<MetadataDTO>(startEvent, clientFactory.getEventBus()) {

				@Override
				public void onSuccess(MetadataDTO result) {
					super.onSuccess(result);
					clientFactory.getEventBus().fireEvent(new NotificationEvent(Message.INSTANCE.savedModifications()));
					ActionStartEvent refreshEvent = new ActionStartEvent(CommonMessages.INSTANCE.refreshing(), ActionEventConstant.REFRESHING_EVENT, true);
					clientFactory.getEventBus().fireEvent(refreshEvent);
					view.edit(result);
					clientFactory.getEventBus().fireEvent(refreshEvent.getEndingEvent());
					previousHash = result.getHash();
					if (mode.compareTo(Constants.CREATE)==0)
					{
						observatoryUuid = result.getOtherPart().getUuid();
						setMode(Constants.MODIFY);
						broadcastActivityTitle(Message.INSTANCE.observatoryEditingViewModificationHeader());
						clientFactory.getBreadCrumb().addShortcut(ShortcutFactory.getObservatoryModificationShortcut(((ObservatoryDTO) result).getObservatoryName(), observatoryUuid));
					}
				}
			});
		}

	}



	@Override
	public void back() {
		//traceHash((ObservatoryDTO) view.flush());
		BreadCrumb breadCrumb = clientFactory.getBreadCrumb();
		List<Shortcut> shortcuts = breadCrumb.getShortcuts();
		if ((shortcuts != null) && (shortcuts.size()>1))
		{
			Shortcut shortcut = shortcuts.get(shortcuts.size() - 2);
			clientFactory.getPlaceController().goTo(shortcut.getPlace());
		}

	}


	@Override
	public void generateXML(MetadataDTO metadataDTO) {
		// TODO Auto-generated method stub

	}

	@Override
	public void validate(MetadataDTO dto) {
		List<ValidationAlert> validationResult = dto.validate();
		if (validationResult.isEmpty() == false)
		{
			DialogBoxTools.popUpScrollable(CommonMessages.INSTANCE.error(), ValidationAlert.toHTML(validationResult), DialogBoxTools.HTML_MODE);
			return;
		}
		else
		{
			DialogBoxTools.modalAlert(CommonMessages.INSTANCE.information(), Message.INSTANCE.noValidationProblems());
		}

	}
	
	@Override
	public void addExperimentalSite() {
		if (isDirty())
		{
			DialogBoxTools.modalAlert(CommonMessages.INSTANCE.information(), Message.INSTANCE.saveObservatoryFirst());
		}
		else
		{
			content = new ExperimentalSiteNameDialogContent(new ConfirmCallBack() {
						
						@Override
						public void confirm(boolean choice) {
							if (choice==true)
							{
								ObservatoryDTO observatoryDTO = (ObservatoryDTO) view.flush();
								ExperimentalSiteEditingPlace experimentalSiteEditingPlace = new ExperimentalSiteEditingPlace();
								experimentalSiteEditingPlace.setExperimentalSiteName(content.getExperimentalSiteName());
								MetadataSummaryDTO parentSummary = new MetadataSummaryDTO();
								parentSummary.setUuid(observatoryDTO.getOtherPart().getUuid());
								parentSummary.setName(observatoryDTO.getObservatoryName());
								experimentalSiteEditingPlace.setParentSummary(parentSummary);
								clientFactory.getPlaceController().goTo(experimentalSiteEditingPlace);
							}
						}
					});
			
			OkCancelDialog dialog = new OkCancelDialog(Message.INSTANCE.experimentalSite(), content);
			dialog.show();
		}
	}


	@Override
	public void deleteExperimentalSite(final String uuid) 
	{
		final ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.deleting(), ActionEventConstant.EXPERIMENTAL_SITE_DELETING_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);
		METADATA_SERVICE.deleteObservatoryEntry(uuid, new DefaultAbstractCallBack<Boolean>(e, clientFactory.getEventBus()) 
		{
			@Override
			public void onSuccess(Boolean result) {
				super.onSuccess(result);
				clientFactory.getEventBus().fireEvent(new NotificationEvent(CommonMessages.INSTANCE.deletedElement()));
				((ObservatoryEntryView) view).broadcastExperimentalSiteDeletion(uuid);
			}
		});
		
	}


	@Override
	public void goToExperimentalSiteEditPlace(MetadataSummaryDTO experimentalSiteSummaryDTO) 
	{
		ExperimentalSiteEditingPlace place = new ExperimentalSiteEditingPlace();
		place.setExperimentalSiteName(experimentalSiteSummaryDTO.getName());
		place.setExperimentalSiteUuid(experimentalSiteSummaryDTO.getUuid());
		clientFactory.getPlaceController().goTo(place);
	}


	@Override
	public void goToExperimentalSiteDisplayPlace(String uuid) {
		ExperimentalSiteEntryDisplayingPlace place = new ExperimentalSiteEntryDisplayingPlace();
		place.setUuid(uuid);
		clientFactory.getPlaceController().goTo(place);
		
	}


	@Override
	public void computeGeographicalBoxes() 
	{
		if (observatoryUuid == null)
		{
			//Observatory is in creation mode, we don't do anything
			return;
		}
		else
		{
			ActionStartEvent startEvent = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstant.EXPERIMENTAL_SITE_LOADING_EVENT, true);
			METADATA_SERVICE.computeGeographicalBoxesFromExperimentalSites(observatoryUuid, new DefaultAbstractCallBack<ArrayList<GeographicBoundingBoxDTO>>(startEvent, clientFactory.getEventBus()) 
			{
				@Override
				public void onSuccess(ArrayList<GeographicBoundingBoxDTO> result) 
				{
					super.onSuccess(result);
					((ObservatoryEntryView) view).setGeographicalBoxes(result);
				}
			});
		}
	}
	
	@Override
	public void loadDirectoryPersons(ObservatoryPersonTable table) {
		loadDirectoryPersonsByObservatoryName(getObservatoryName(), table);
	}


	@Override
	public String getObservatoryName() 
	{
		return observatoryName;
	}

}
